package com.jf.net

import android.util.Pair
import com.jf.net.adapter.FlowDataCallFactory
import com.jf.net.converter.GsonConverterFactory
import com.jf.net.interceptor.CacheInterceptor
import com.jf.net.interceptor.LogInterceptor
import com.jf.net.interceptor.RequestInterceptor
import com.jf.net.utils.AppUtil
import okhttp3.Cache
import okhttp3.Interceptor
import okhttp3.OkHttpClient
import okhttp3.logging.HttpLoggingInterceptor
import retrofit2.CallAdapter
import retrofit2.Converter
import retrofit2.Retrofit
import java.io.File
import java.util.concurrent.TimeUnit
import javax.net.ssl.SSLSocketFactory
import javax.net.ssl.X509TrustManager

/**
 * PlatformApi
 * @author hao.yin
 * @time 2023/10/20 11:33
 * @description
 */
class NetServiceHelper private constructor() {

    companion object {

        val instance: NetServiceHelper by lazy(LazyThreadSafetyMode.SYNCHRONIZED) {
            NetServiceHelper()
        }
        const val CACHE_SIZE = 1024 * 1024 * 100L
        const val CACHE_FILE_PATH = "httpCache"
        const val API_CONNECT_TIME_OUT = 60L
        const val API_READ_TIME_OUT = 60L
        const val API_WRITE_TIME_OUT = 60L

        @JvmStatic
        val DEFAULT_INTERCEPTORS_DEBUG by lazy {
            arrayListOf(
                LogInterceptor(),
                HttpLoggingInterceptor().apply { level = HttpLoggingInterceptor.Level.BODY }
            )
        }

        @JvmStatic
        val DEFAULT_INTERCEPTORS_RELEASE by lazy {
            arrayListOf(
                RequestInterceptor(),
                LogInterceptor()
            )
        }

        @JvmStatic
        val DEFAULT_NET_INTERCEPTORS by lazy {
            arrayListOf(CacheInterceptor())
        }

        @JvmStatic
        val DEFAULT_CONVERTS by lazy {
            arrayListOf(GsonConverterFactory.create())
        }

        @JvmStatic
        val DEFAULT_ADAPTERS by lazy {
            arrayListOf(FlowDataCallFactory.create())
        }
    }

    @JvmOverloads
    fun <T> create(
        url: String,
        clz: Class<T>,
        netInterceptors: List<Interceptor> = DEFAULT_NET_INTERCEPTORS,
        //interceptors: List<Interceptor> = if (BuildConfig.DEBUG) DEFAULT_INTERCEPTORS_DEBUG else DEFAULT_INTERCEPTORS_RELEASE,
        interceptors: List<Interceptor> = DEFAULT_INTERCEPTORS_RELEASE,
        converts: List<Converter.Factory> = DEFAULT_CONVERTS,
        adapters: List<CallAdapter.Factory> = DEFAULT_ADAPTERS,
        socketFactory: Pair<SSLSocketFactory, X509TrustManager>,
        cacheSize: Long = CACHE_SIZE
    ): T = getRetrofit(url, netInterceptors, interceptors, converts, adapters, socketFactory, cacheSize).create(clz)

    @JvmOverloads
    fun <T> create(
        url: String,
        clz: Class<T>,
        converts: List<Converter.Factory> = DEFAULT_CONVERTS,
        adapters: List<CallAdapter.Factory> = DEFAULT_ADAPTERS,
        okhttpBuilder : OkHttpClient.Builder
    ): T = getRetrofit(url, converts, adapters, okhttpBuilder).create(clz)


    fun getRetrofit(
        url: String,
        netInterceptors: List<Interceptor>,
        interceptors: List<Interceptor>,
        converts: List<Converter.Factory>,
        adapters: List<CallAdapter.Factory>,
        socketFactory: Pair<SSLSocketFactory, X509TrustManager>,
        cacheSize: Long,
    ): Retrofit {
        //okHttpClient
        val okhttpBuilder = getOkHttpClient(netInterceptors, interceptors, socketFactory, cacheSize);
        //baseUrl以及okHttpClient设置
        val builder = Retrofit.Builder()
            .baseUrl(url)
            .client(okhttpBuilder.build())
        //自定义转换器
        converts.forEach {
            builder.addConverterFactory(it)
        }
        //自定义适配器
        adapters.forEach {
            builder.addCallAdapterFactory(it)
        }
        return builder.build()
    }

    fun getRetrofit(
        url: String,
        converts: List<Converter.Factory>,
        adapters: List<CallAdapter.Factory>,
        okhttpBuilder : OkHttpClient.Builder
    ): Retrofit {
        //baseUrl以及okHttpClient设置
        val builder = Retrofit.Builder()
            .baseUrl(url)
            .client(okhttpBuilder.build())
        //自定义转换器
        converts.forEach {
            builder.addConverterFactory(it)
        }
        //自定义适配器
        adapters.forEach {
            builder.addCallAdapterFactory(it)
        }
        return builder.build()
    }

    @JvmOverloads
    fun getOkHttpClient(netInterceptors: List<Interceptor> = DEFAULT_NET_INTERCEPTORS,
                        interceptors: List<Interceptor>,
                        socketFactory: Pair<SSLSocketFactory, X509TrustManager>?,
                        cacheSize: Long): OkHttpClient.Builder {
        //缓存设置
        val cache = Cache(File(AppUtil.getAppContext().cacheDir, CACHE_FILE_PATH), cacheSize)
        val builder = OkHttpClient.Builder()
        //自定义NetworkInterceptor
        netInterceptors.forEach {
            builder.addNetworkInterceptor(it)
        }
        //自定义通用拦截器
        interceptors.forEach {
            builder.addInterceptor(it)
        }
        //自定义证书
        socketFactory?.let {
            builder.sslSocketFactory(it.first, it.second)
        }
        return builder
            .cache(cache)
            .connectTimeout(API_CONNECT_TIME_OUT, TimeUnit.SECONDS)
            .readTimeout(API_READ_TIME_OUT, TimeUnit.SECONDS)
            .writeTimeout(API_WRITE_TIME_OUT, TimeUnit.SECONDS)
    }
}